//////////////////////////////////////////////
// FunctionParameter.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkScripts
{
	class UserType ;
}

/// Includes ---------------------------------

// nkScripts
#include "../../Dll/DllDefines.h"

#include "../ScriptObjects/ScriptObjectReference.h"
#include "../ScriptObjects/ScriptObjectView.h"

#include "FunctionParameterType.h"

// nkMemory
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

// Standards
#include <string>

/// Internals --------------------------------

namespace nkScripts
{
	struct UserTypeHolder
	{
		// Il nous faut le pointeur et le nom du user type
		nkMemory::String _userTypeName ;
		void* _userData = nullptr ;
		ScriptObjectView _objectRef ;
	} ;
}

/// Class ------------------------------------

namespace nkScripts
{
	struct DLL_SCRIPTS_EXPORT FunctionParameter final
	{
		// Functions
		// Constructor, destructor
		FunctionParameter () noexcept ;
		explicit FunctionParameter (bool val) noexcept ;
		explicit FunctionParameter (int val) noexcept ;
		explicit FunctionParameter (float val) noexcept ;
		explicit FunctionParameter (double val) noexcept ;
		FunctionParameter (const char* val) noexcept ;
		FunctionParameter (nkMemory::StringView val) noexcept ;
		FunctionParameter (void* val, nkMemory::StringView userTypeName, bool scriptOwner) noexcept ;
		FunctionParameter (const ScriptObjectReference& scriptObjectReference) noexcept ;
		FunctionParameter (const FunctionParameter& other) noexcept ;
		FunctionParameter (FunctionParameter&& other) noexcept ;
		~FunctionParameter () ;

		// Helpers
		void prepareForInternalType () ;
		void prepareForString () ;
		void prepareForUserType () ;
		void prepareForScriptObjectReference () ;

		// Operators
		FunctionParameter& operator= (const FunctionParameter& other) noexcept ;
		FunctionParameter& operator= (FunctionParameter&& other) noexcept ;

		// Attributes
		union
		{
			bool _valBool ;
			int _valInt ;
			float _valFloat ;
			double _valDouble ;
			nkMemory::String _valString ;
			UserTypeHolder _valUser ;
			ScriptObjectReference _valScriptObject ;
		} ;

		FUNCTION_PARAMETER_TYPE _type ;

		// Static output for void
		static FunctionParameter VOID ;
	} ;
}